﻿using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;

namespace Games.Common
{
    public class MaskGrid : Grid
    {
        private Grid Mask;
        private Grid Content;
        private StackLayout toolbar;
        private Label lblTitle;
        private Dictionary<string, string> titles = new Dictionary<string, string>();
        private Dictionary<string, View> chidren = new Dictionary<string, View>();
        private Dictionary<string, Size> sizes = new Dictionary<string, Size>();
        private Dictionary<string, Action> callbacks = new Dictionary<string, Action>();
        private bool isInited;
        private string currentName;
        private int pWidth, pHeight;
        private Button btnOk, btnCancel;

        public MaskGrid()
        {
            this.IsVisible = false;
        }

        public void Init()
        {
            if(isInited)
            {
                return;
            }
            isInited = true;
            var p = this.Parent as View;
            pWidth = (int)p.Width;
            pHeight = (int)p.Height;
            this.IsVisible = false;
            Mask = new Grid { BackgroundColor = Color.Gray, Opacity = 0.3 };
            this.Children.Add(Mask);

            Content = new Grid { BackgroundColor = Color.White };
            Content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            Content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
            Content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            this.Children.Add(Content, 0, 0);

            var titleGrid = new Grid { BackgroundColor = Color.White };
            lblTitle = new Label
            {
                FontSize = 30,
                HorizontalTextAlignment = TextAlignment.Center,
                TextColor = Color.Black
            };
            titleGrid.Children.Add(lblTitle);
            Content.Children.Add(titleGrid, 0, 0);

            toolbar = new StackLayout { Margin = new Thickness(10, 0, 10, 10), BackgroundColor = Color.White, Orientation = StackOrientation.Horizontal };
            Content.Children.Add(toolbar, 0, 2);

            btnOk = new Button();
            toolbar.Children.Add(btnOk);
            btnCancel = new Button();
            toolbar.Children.Add(btnCancel);
            btnOk.Clicked += (sender, e) => this.Hide(true);
            btnCancel.Clicked += (sender, e) => this.Hide(false);
            SetValue(BackgroundColorProperty, Color.Transparent);
            this.IsVisible = false;
        }

        public View Get(string name)
        {
            if(this.chidren.ContainsKey(name))
            {
                return this.chidren[name];
            }
            return null;
        }

        public bool Contains(string name)
        {
            return this.chidren.ContainsKey(name);
        }
        public bool Contains(View view)
        {
            return this.chidren.Values.Contains(view);
        }
        public void Add(string name, string title, View view)
        {
            if(name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if(view == null)
            {
                throw new ArgumentNullException(nameof(view));
            }
            this.Init();
            if(this.chidren.ContainsKey(name))
            {
                var exits = this.chidren[name];
                if(exits != view)
                {
                    if(this.Content.Children.Contains(exits))
                    {
                        this.Content.Children.Remove(exits);
                    }
                }
            }
            this.chidren[name] = view;
            if(string.IsNullOrWhiteSpace(title))
            {
                title = name;
            }
            this.titles[name] = title;
            if(!this.Content.Children.Contains(view))
            {
                this.Content.Children.Add(view, 0, 1);
            }
            view.IsVisible = false;
        }
        public void SetSize(string name, double widthRate, double heightRate)
        {
            this.Init();
            if(widthRate > 1)
            {
                widthRate = 1;
            }
            else if(widthRate < 0)
            {
                widthRate = 0.8;
            }
            if(heightRate > 1)
            {
                heightRate = 1;
            }
            else if(heightRate < 0)
            {
                heightRate = 0.7;
            }
            int width = (int)(pWidth * widthRate);
            int height = (int)(pHeight * heightRate);
            this.sizes[name] = new Size(width, height);
        }

        public void SetSize(string name, int width, int height)
        {
            this.sizes[name] = new Size(width, height);
        }
        public void Callback(string name, Action action)
        {
            this.callbacks[name] = action;
        }

        public void Remove(string name)
        {
            this.Init();
            if(this.chidren.ContainsKey(name))
            {
                var exits = this.chidren[name];
                if(this.Content.Children.Contains(exits))
                {
                    this.Content.Children.Remove(exits);
                }
                this.chidren.Remove(name);
            }
            if(this.titles.ContainsKey(name))
            {
                this.titles.Remove(name);
            }
            if(this.sizes.ContainsKey(name))
            {
                this.sizes.Remove(name);
            }
            if(this.callbacks.ContainsKey(name))
            {
                this.callbacks.Remove(name);
            }
        }
        //public bool Toggle(string name, bool showButtons = true)
        //{
        //    this.Init();
        //    if(this.chidren.ContainsKey(name))
        //    {
        //        if(this.chidren[name].IsVisible)
        //        {
        //            this.Hide();
        //        }
        //        else
        //        {
        //            return this.Show(name, showButtons);
        //        }
        //    }
        //    return false;
        //}
        public bool Show(string name)
        {
            return this.Show(name, null, null);
        }
        public bool ShowWithOk(string name, string ok = "确定")
        {
            return this.Show(name, ok, null);
        }
        public bool ShowWithCancel(string name, string cancel = "取消")
        {
            return this.Show(name, null, cancel);
        }
        public bool ShowWithOkCancel(string name, string ok = "确定", string cancel = "取消")
        {
            return this.Show(name, ok, cancel);
        }
        private bool Show(string name, string ok, string cancel)
        {
            this.Init();
            if(this.chidren.ContainsKey(name))
            {
                this.chidren[name].IsVisible = true;
                this.currentName = name;
                if(this.sizes.ContainsKey(name))
                {
                    int mw = 30, mh = 50;
                    var size = this.sizes[name];
                    if(size.Width > 0)
                    {
                        mw = (int)(pWidth - size.Width) / 2;
                        mw = Math.Max(0, mw);
                    }
                    if(size.Height > 0)
                    {
                        mh = (int)(pHeight - size.Height) / 2;
                        mh = Math.Max(0, mh);
                    }
                    this.Content.Margin = new Thickness(mw, mh);
                }
                else
                {
                    this.Content.Margin = new Thickness(30, 50, 30, 100);
                }
                this.lblTitle.Text = this.titles[name];
                this.IsVisible = true;
                if(!string.IsNullOrWhiteSpace(ok))
                {
                    this.btnOk.Text = ok;
                    this.btnOk.IsVisible = true;
                }
                else
                {
                    this.btnOk.IsVisible = false;
                }
                if(!string.IsNullOrWhiteSpace(cancel))
                {
                    this.btnCancel.Text = cancel;
                    this.btnCancel.IsVisible = true;
                }
                else
                {
                    this.btnCancel.IsVisible = false;
                }
                return true;
            }
            return false;
        }

        public void Hide()
        {
            this.Hide(false);
        }

        private void Hide(bool isOk)
        {
            this.Init();
            this.IsVisible = false;
            foreach(var item in chidren.Values)
            {
                item.IsVisible = false;
            }
            if(isOk)
            {
                if(this.currentName != null && this.callbacks.ContainsKey(this.currentName))
                {
                    var action = this.callbacks[this.currentName];
                    action?.Invoke();
                }
            }
            this.currentName = null;
        }
    }
}